﻿using System;
using System.Collections.Generic;
using System.Text;
using ThoughtWorks.CruiseControl.Core;
using ThoughtWorks.CruiseControl.Remote;
using Exortech.NetReflector;
using Microsoft.TeamFoundation.Client;
using Microsoft.TeamFoundation.VersionControl.Client;
using System.Collections;
using System.Net;
using System.Threading;

namespace ccnet.tfsrevisionlabeller.plugin
{
    [ReflectorType("tfsRevisionLabeller")]
    public class TfsRevisionLabeller : ITask, ILabeller
    {
        public TfsRevisionLabeller()
        {

        }

        #region ITask Members

        public void Run(IIntegrationResult result)
        {
            result.Label = this.Generate(result);
        }

        #endregion

        #region ILabeller Members

        public string Generate(IIntegrationResult integrationResult)
        {
            string version = "0.0.0";
                       
            TeamFoundationServer tfs = new TeamFoundationServer(TfsServer,Credentials);

            // Get a reference to Version Control.
            VersionControlServer versionControl = (VersionControlServer)tfs.GetService(typeof(VersionControlServer));

            IEnumerable changeSets = versionControl.QueryHistory(TfsProjectPath, VersionSpec.Latest, 0, RecursionType.Full, null, null, null, 1, true, false);

            int latestChangesetId = 0;

            // there is only one  
            foreach (Changeset c in changeSets)
            {
                latestChangesetId = c.ChangesetId;
            }

            _build = latestChangesetId;
                        
            version = string.Format("{0}{1}.{2}.{3}", Prefix, Major, Minor, Build);  //latestChangesetId.ToString();

            return version;
        }

        #endregion

        [ReflectorProperty("tfsServer",Required=true)]
        public string TfsServer { get; set; }

        [ReflectorProperty("tfsProjectPath", Required = true)]
        public string TfsProjectPath { get; set; }

        /// <summary>
        /// Gets or sets the username that will be used to access the Tfs repository.
        /// </summary>
        /// <value>The username.</value>
        /// 
        private string _username = Environment.UserName;
        [ReflectorProperty("username", Required = false)]        
        public string Username 
        {
            get { return _username; }
            set { _username = value; }
        }

        /// <summary>
        /// Gets or sets the password that will be used to access the Tfs repository.
        /// </summary>
        /// <value>The password.</value>
        [ReflectorProperty("password", Required = true)]
        public string Password { get; set; }

        private string _domain = Environment.UserDomainName;
        [ReflectorProperty("domain", Required = false)]        
        public string Domain 
        {
            get { return _domain; }
            set { _domain = value; } 
        }

        /// <summary>
        /// Gets or sets the major version.
        /// </summary>
        /// <value>The major version number.</value>
        /// 
        private int _major = 1;
        [ReflectorProperty("major", Required = false)]
        public int Major 
        {
            get { return _major; }
            set { _major = value; } 
        }

        /// <summary>
        /// Gets or sets the minor version.
        /// </summary>
        /// <value>The minor version number.</value>
        /// 
        private int _minor = 0;
        [ReflectorProperty("minor", Required = false)]
        public int Minor 
        {
            get { return _minor; }
            set { _minor = value; } 
        }

        /// <summary>
        /// Gets or sets the build number.
        /// </summary>
        /// <value>The build number.</value>
        /// 
        private int _build = -1;
        [ReflectorProperty("build", Required = false)]        
        public int Build 
        {
            get { return _build; }
            set { _build = value; } 
        }

        [ReflectorProperty("prefix", Required = false)]
        public string Prefix { get; set; }

        private NetworkCredential networkCredential;
        /// <summary>
        ///   Network credentials used to interact with TFS.
        /// </summary>
        public NetworkCredential Credentials
        {
            get
            {
                if (null == networkCredential)
                {
                    if (Username != null && Password != null)
                    {
                        if (Domain != null)
                            networkCredential = new NetworkCredential(Username, Password, Domain);
                        else
                            networkCredential = new NetworkCredential(Username, Password);
                    }
                    else
                    {
                        networkCredential = CredentialCache.DefaultNetworkCredentials;
                    }
                }
                return networkCredential;
            }
            set
            {
                networkCredential = value;
            }
        }
    }
}
